package com.gonsin.ta.logic.controllers;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.gonsin.ta.logic.config.BaseTaConfig;
import com.gonsin.ta.logic.controllers.po.*;
import com.gonsin.ta.logic.node.Node;
import com.gonsin.ta.logic.node.TaNodeBuilder;
import com.gonsin.ta.logic.node.groovy.GroovyNodeAdapter;
import com.gonsin.ta.logic.node.groovy.GroovyScriptExecutor;
import com.gonsin.ta.logic.parse.TaChainBuilder;
import com.gonsin.ta.logic.process.TaResponse;
import com.gonsin.ta.logic.exceptions.TaException;
import com.gonsin.ta.logic.parse.TaExecutorService;
import com.gonsin.ta.logic.process.SignalCenter;
import com.gonsin.ta.logic.process.TaBus;
import com.gonsin.ta.logic.parse.Chain;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Api(tags = "TA框架开放接口")
@RestController
@RequestMapping("/api/ta")
public class TaController {

    @Autowired private SignalCenter signalCenter;
    @Autowired private TaExecutorService executorService;
    @Autowired private BaseTaConfig taConfig;
    @Autowired private GroovyScriptExecutor groovyScriptExecutor;

    @ApiOperationSupport(order = 2)
    @ApiOperation("TA - 发出信号")
    @PostMapping("/signal")
    public BaseResponse<TaResponse> postSignal(@RequestBody TaSignalPost signal){
        TaResponse success = signalCenter.post(signal);
        return BaseResponse.result(success);
    }

    @ApiOperationSupport(order = 3)
    @ApiOperation("TA - 查询所有流程")
    @PostMapping("/chains")
    public BaseResponse<Collection<Chain>> findChains(@ApiIgnore HttpServletRequest request){
        String token = request.getHeader("token");

        return BaseResponse.result(TaBus.getChainMap().values());
    }

    @ApiOperationSupport(order = 4)
    @ApiOperation("TA - 查询所有节点")
    @PostMapping("/nodes")
    public BaseResponse<Collection<Node>> findNodes(){
        return BaseResponse.result(TaBus.getNodeMap().values());
    }


    @ApiOperationSupport(order = 4)
    @ApiOperation("TA - 查询一个节点")
    @PostMapping("/nodes/{nodeId}")
    public BaseResponse<NodeScriptPo> findNodes(@PathVariable("nodeId") String nodeId){
        Node node = TaBus.getNode(nodeId);

        NodeScriptPo script = new NodeScriptPo();
        if(node instanceof GroovyNodeAdapter){
            script.setGroovyScript(((GroovyNodeAdapter) node).getGroovyScript());
        }
        script.setNodeType(node.getNodeType().name());
        script.setNodeId(node.getNodeId());
        return BaseResponse.result(script);
    }



    @ApiOperationSupport(order = 6)
    @ApiOperation("TA - 修改一个节点脚本")
    @PutMapping("/nodes/{nodeId}")
    public BaseResponse<Void> updateNodeScript(@ApiParam("节点id") @PathVariable("nodeId") String nodeId, @RequestBody NodeScriptPo scriptPo,
                                               @ApiIgnore HttpServletRequest request) throws IOException {
        Node node = TaBus.getNode(nodeId);
        if(node == null){
            throw new TaException("查找不到nodeId = 【{}】的节点", nodeId);
        }

        if(StringUtils.isEmpty(StringUtils.trim(scriptPo.getGroovyScript()))){
            throw new TaException("脚本不能为空");
        }

        String filename = null;
        if(node instanceof GroovyNodeAdapter){
            filename = ((GroovyNodeAdapter) node).getFilename();
            TaNodeBuilder.createBuilder(groovyScriptExecutor)
                    .setNodeType(node.getNodeType())
                    .setNodeId(node.getNodeId())
                    .setGroovyScript(scriptPo.getGroovyScript())
                    .setFilename(filename)
                    .build();
        } else {
            // 解析脚本内容，获取类名
            Class clazz = groovyScriptExecutor.parseClass(node.getNodeId(), node.getNodeType(), scriptPo.getGroovyScript());
            if(clazz != null){
                filename = clazz.getName() + ".ta.xml";
                TaNodeBuilder.createBuilder(groovyScriptExecutor)
                        .setNodeType(node.getNodeType())
                        .setNodeId(node.getNodeId())
                        .setClass(clazz)
                        .setGroovyScript(scriptPo.getGroovyScript())
                        .setFilename(filename)
                        .build();
            } else {
                filename = new SimpleDateFormat("YYYY-MM-dd_HH-mm-ss").format(new Date()) + ".ta.xml";
                TaNodeBuilder.createBuilder(groovyScriptExecutor)
                        .setNodeType(node.getNodeType())
                        .setNodeId(node.getNodeId())
                        .setGroovyScript(scriptPo.getGroovyScript())
                        .setFilename(filename)
                        .build();
            }
        }

        TaBus.cleanCache();

        // TODO 持久化修改的内容

        return BaseResponse.result();

    }


    @ApiOperationSupport(order = 5)
    @ApiOperation("TA - 查询一个流程")
    @PostMapping("/chains/{chainId}")
    public BaseResponse<Chain> getChainScript(@ApiParam("流程id") @PathVariable("chainId") String chainId){
        Chain chain = TaBus.getChain(chainId);
        if(chain == null){
            throw new TaException("查找不到chainId = 【{}】的流程", chainId);
        }
        return BaseResponse.result(chain);
    }


    @ApiOperationSupport(order = 6)
    @ApiOperation("TA - 修改一个流程脚本")
    @PutMapping("/chains/{chainId}")
    public BaseResponse<Void> updateChainScript(@ApiParam("流程id") @PathVariable("chainId") String chainId, @RequestBody ChainScriptPo scriptPo,
                                             @ApiIgnore HttpServletRequest request) throws IOException {
        Chain chain = TaBus.getChain(chainId);
        if(chain == null){
            throw new TaException("查找不到chainId = 【{}】的流程", chainId);
        }

        String ql = scriptPo.getQlScript();

        if(StringUtils.isEmpty(StringUtils.trim(ql))){
            throw new TaException("脚本不能为空");
        }

        TaChainBuilder.createChain(signalCenter)
                .setChainId(chainId)
                .setFilename(chain.getFilename())
                .setChainName(chain.getChainName())
                .enableReplace(true)
                .setQL(ql)
                .build();

        // TODO 持久化修改的内容

        return BaseResponse.result();

    }

//    @ApiOperationSupport(order = 7)
//    @ApiOperation("TA - 用户登录")
//    @PostMapping("/user/login")
//    public BaseResponse<String> login(
//            @ApiIgnore HttpServletRequest request,
//            @RequestParam("username") String username, @RequestParam("password") String password){
//        if(!StringUtils.equals(taConfig.getUser(), username) || !StringUtils.equals(taConfig.getPassword(), password)){
//            throw new TaException("密码或账号错误");
//        }
//
//        if(!CollectionUtils.isEmpty(taConfig.getWhiteList())){
//            String ip = request.getRemoteAddr();
//            if(!taConfig.getWhiteList().contains(ip)){
//                throw new TaException("{}不在白名单中", ip);
//            }
//        }
//
//        if(!CollectionUtils.isEmpty(taConfig.getBlackList())){
//            String ip = request.getRemoteAddr();
//            if(taConfig.getWhiteList().contains(ip)){
//                throw new TaException("{}在黑名单中", ip);
//            }
//        }
//
//        Map<String, Object> userInfo = new HashMap<>();
//        userInfo.put("user", username);
//        userInfo.put("validate", System.currentTimeMillis() + 1000 * 60 * 60 * 24);
//        String token =
//                Jwts.builder()
//                        .setClaims(userInfo)
//                        .signWith(SignatureAlgorithm.HS256, Constant.JWT_SIGNING_KEY)
//                        .compact();
//        return BaseResponse.result(token);
//    }

//    @ApiOperationSupport(order = 8)
//    @ApiOperation("TA - 用户信息")
//    @GetMapping("/user/info")
//    public BaseResponse<Object> info(@RequestParam("token") String token){
//        Jwt jwt = Jwts.parser()
//                .setSigningKey(Constant.JWT_SIGNING_KEY)
//                .parse(token);
//        return BaseResponse.result(jwt.getBody());
//    }
//
//    @ApiOperationSupport(order = 8)
//    @ApiOperation("TA - 用户登出")
//    @GetMapping("/user/logout")
//    public BaseResponse<String> logout(@RequestParam("token") String token){
//        Jwt jwt = Jwts.parser()
//                .setSigningKey(Constant.JWT_SIGNING_KEY)
//                .parse(token);
//        Map<String, Object> map = new HashMap<>();
//        map.clear();
//        return BaseResponse.result();
//    }

}
